package com.zoe.thread.th12_线程池自定义;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

/**
 * @Author Zoe
 * @Date: 2021/05/05
 * @Description 自定义线程池
 * <p>
 * AbortPolicy(默认)：直接抛出RejectedExecutionException异常阻止系统正常运行
 * <p>
 * CallRunsPolicy:“调用者运行”一种调节机制，该策略既不会抛弃任务，也不
 * 会抛出异常，而是将某些任务回退到调用者，从而降低新任务的流量。（谁调用的回退给谁调用）
 * <p>
 * DiscardOldestPolicy:抛弃队列中等待最久的任务，然后把当前任务加人队列中尝试再次提交当前任务。
 * <p>
 * DiscardPolicy：该策略默默地丢弃无法处理的任务，不予任何处理也不抛出异常。如果允许任务丢失，这是最好的一种策略。
 */
public class MyThreadPoolDemo {
    private static final Logger logger = LoggerFactory.getLogger(MyThreadPoolDemo.class);

    public static void main(String[] args) throws InterruptedException {
        // 获取CPU核数
        System.out.println(Runtime.getRuntime().availableProcessors());
        int CPUCount = Runtime.getRuntime().availableProcessors();
        // 同时容纳的任务数 = （ max + que ）, 超过这个数量会触发拒绝策略
        ExecutorService executorService = new ThreadPoolExecutor(
                5,//  如果是CPU密集型这个参数就是(CPU核数+1),如果是IO密集型2*CUP核心数+1
                5,
                5,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(5),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy() // 丢弃任务，并抛出拒绝执行 RejectedExecutionException 异常信息。线程池默认的拒绝策略。必须处理好抛出的异常，否则会打断当前的执行流程，影响后续的任务执行。
                //             new ThreadPoolExecutor.CallerRunsPolicy() // 回退给调用者处理
                //            new ThreadPoolExecutor.DiscardOldestPolicy() // 丢弃队列中等待最久的
                // new ThreadPoolExecutor.DiscardPolicy()  // 丢弃无法处理的任务，不予任何处理也不抛出异常。
        );

        threadPool(executorService);


    }

    public static void threadPool(ExecutorService executorService) {
        try {
            for (int i = 1; i <= 10; i++) {
                int finalI = i;
                executorService.execute(() -> {
                    try {
                        logger.info(Thread.currentThread().getName() + "加入任务   " + finalI);
                        TimeUnit.SECONDS.sleep(5);
                        monitorExecutor(executorService);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            executorService.shutdown();
        }
    }

    public synchronized static void monitorExecutor(ExecutorService executorService) {
        ThreadPoolExecutor tpe = (ThreadPoolExecutor) executorService;
        System.out.println();
        System.out.println("当前排队线程数：" + tpe.getQueue().size());

        System.out.println("当前活动线程数：" + tpe.getActiveCount());

        System.out.println("可以同时执行的线程程数：" + tpe.getLargestPoolSize());

        System.out.println("执行完成线程数：" + tpe.getCompletedTaskCount());

        System.out.println("预估线程任务总数：" + tpe.getTaskCount());

        System.out.println();
    }
}
